package com.pan.download4.search;

import com.pan.crawler.Search;
import com.pan.download4.enumn.Line;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

public class SearchDriver {


    private static final String SEARCH_CLASS_NAME = "com.pan.crawler.impl{}.SearchImpl{}";

    private List<Search> searchList;

    private ThreadPoolExecutor searchPool;{
    }

    public SearchDriver(){
        int count = Line.values().length;
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(count,
                count, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),
                new ThreadPoolExecutor.CallerRunsPolicy());
        List<FutureTask> futureTaskList = new ArrayList<>();
        for (Line l : Line.values()) {
            String searchClassName = SEARCH_CLASS_NAME.replace("{}",l.getNumber());
            Callable<Search> callable = new Callable() {
                @Override
                public Search call(){
                    try {
                        Class<?> searchClass = Class.forName(searchClassName);
                        Search search = (Search) searchClass.getConstructor().newInstance();
                        return search;
                    }catch (Exception e){
                        return null;
                    }
                }
            };
            FutureTask futureTask = new FutureTask<>(callable);
            futureTaskList.add(futureTask);
            poolExecutor.submit(futureTask);
        }
        searchList = new ArrayList<>();
        searchList= futureTaskList.stream()
                .map(task -> {
                    try {
                        return (Search)task.get();
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                })
                .filter(search -> search == null ? false : true)
                .collect(Collectors.toList());
        poolExecutor.shutdown();
        int searchCount = searchList.size();
        searchPool = new ThreadPoolExecutor(searchCount,searchCount,10,
                TimeUnit.SECONDS,new ArrayBlockingQueue<>(10));
    }

    public void find(String content){
        for (Search search : searchList) {
            searchPool.execute(()->{
                search.find(content);
            });
        }
    }
    public void close(){
        searchList.forEach(Search::close);
        searchPool.shutdown();;
    }



}
